#include "commands.h"
#include "commands_allegro.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

// All available commands
const struct avgdl_command_prototype avgdl_command_list[] = {
         
	/* world
	 *
	 * arguments:
	 * 0: world name
	 *
	 * creates a world (if a world doesn't exist with that name)
	 * sets it as active world
	 */
	{"world", 1},

	/* object
	 *
	 * args:
	 * 0: object name
	 *
	 * creates new object with given name
	 */
	{"object", 1},

};

// Number of commands
const int avgdl_command_list_size = sizeof(avgdl_command_list)
	/sizeof(struct avgdl_command_prototype);


char *translate_abstract(char* exec, struct avgdl_command *cmd) {

	// Create new array with translated key-content pairs
	char *native;

	// Content (translation should happen here)
	int orig_size = sizeof(char) *strlen(exec) +1;
	char *orig = exec;
	native = malloc(orig_size);
	native[0] = '\0';

	char *start = orig;
	char *end = orig;

	while (*start != '\0') {
		end = strstr(start, "\\");

		// Found backslash
		if (end != NULL) {

			strncat(native, start, end -start);

			int recognised = 0;
			for (int j = 0; j < 9; j++) {
				char key[2];
				key[0] = '\\';
				key[1] = '1' +j;
				// Backslash is recognized - replace it and continue
				if (strncmp(end, key, 2) == 0) {
					// add substitution to native
					orig_size = orig_size -2 +strlen((char*)(cmd->arg+j));
					native = realloc(native, orig_size);
					if (!native) {
						printf("error on realloc\n");
					}
					strcat(native, (char*)(cmd->arg+j));

					// advance start to skip backslash and number
					start = end+2;
					recognised = 1;
					break;
				}
			}

			if (recognised) continue;

			// Backlash not recognized - cat the backslash to the string and continue
			strcat(native, "\\"); // TODO fix
			start = end+1;
			continue;
		}

		// No more backslashes, just cat the rest
		strcat(native, start);
		break;
	}

	return native;

}

// Translates code from abstract command to specific code
struct avgdl_return *get_native_code(struct avgdl_command *cmd) {

	struct avgdl_return *code = malloc(sizeof(struct avgdl_return));

	// Get the id of the <lang> command
	int id = -1;
	for (int i = 0; i < allegro_action_size; i++) {
		if (strcmp(cmd->name, allegro_action_list[i].name) == 0) {
			id = i;
		}
	}

	// Command doesn't exist
	if (id == -1) {
		return 0;
	}

	// Save return type
	code->type = allegro_action_list[id].type;

	if (allegro_action_list[id].type == RAW) {

		code->data = translate_abstract(allegro_action_list[id].exec, cmd);
		return code;
	}
	else
	if (code->type == NATIVE) {
		code->data = malloc(sizeof(char**));

		char **data = code->data;
		data[0] = ((char**)allegro_action_list[id].exec)[0];
		data[1] = translate_abstract(
			((char**)allegro_action_list[id].exec)[1],
			cmd);

		return code;
	}

	// return array of native code
	return 0;

} // get native code

